package com.lhl.mq.mqServer.core;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.lhl.mq.common.ConsumerEnv;
import com.lhl.mq.mqServer.datacenter.DataBaseManager;

import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * 表示一个存储消息的队列
 */
public class MSGQueue {
    //表示队列的唯一身份标识
    private String name;
    //表示队列是否需要持久化， true 表示需要持久化， false 表示不需要持久化
    private boolean durable = false;
    //独占，表示这个队列只能一个消费者使用， true 表独占， false 表不独占
    private boolean exclusive = false;
    //预留字段，无人使用时自动删除
    private boolean autoDelete = false;
    //预留字段，交换机的其他参数
    private Map<String, Object> arguments = new HashMap<>();
    //订阅了该队列消息的消费者
    private List<ConsumerEnv> consumerEnvList = new ArrayList<>();
    //记录当前的消费者
    private AtomicInteger consumerSeq = new AtomicInteger(0);

    //添加订阅消息的消费者
    public void addConsumerEnv(ConsumerEnv consumerEnv){
        consumerEnvList.add(consumerEnv);
    }
    //删除消费者暂不实现

    //以轮询的方式发送消息给消费者
    //挑选一个消费者来处理当前的消息
    public ConsumerEnv chooseConsumer(){
        if (consumerEnvList.size() == 0){
            //说明当前没有消费者订阅该队列的消息
            return null;
        }
        int index = consumerSeq.get() % consumerEnvList.size();
        consumerSeq.incrementAndGet();
        return consumerEnvList.get(index);
    }


    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public boolean isDurable() {
        return durable;
    }

    public void setDurable(boolean durable) {
        this.durable = durable;
    }

    public boolean isExclusive() {
        return exclusive;
    }

    public void setExclusive(boolean exclusive) {
        this.exclusive = exclusive;
    }

    public boolean isAutoDelete() {
        return autoDelete;
    }

    public void setAutoDelete(boolean autoDelete) {
        this.autoDelete = autoDelete;
    }

    //这组get、set方法主要是提供给数据库使用
   public String getArguments(){
       ObjectMapper objectMapper = new ObjectMapper();
       //将 arguments 进行序列化
       try {
          return objectMapper.writeValueAsString(arguments);
       } catch (JsonProcessingException e) {
           e.printStackTrace();
       }

       return "{}";
   }

    //从数据库中读数据
    public void setArguments(String argumentsJson){
        ObjectMapper objectMapper = new ObjectMapper();
        //将变量 arguments 进行反序列化
        try {
            //赋值给当前对象的 argument 属性
            this.arguments = objectMapper.readValue(argumentsJson, new TypeReference<Map<String,Object>>() {});
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }
    }

    //这组get、set方法主要是提供给java内部代码使用，这样取值和赋值都会比较方便
    public Object getArguments(String key){
        return arguments.get(key);
    }

    public void setArguments(String key,Object value){
        arguments.put(key,value);
    }

    public void setArguments(Map<String, Object> arguments){
        this.arguments = arguments;
    }
}
